<template>
  <div style="margin: 0;padding: 0">
    <el-container>
      <!--页面表头设计-->
      <el-header style="height: 42px; display: flex; align-items: center; justify-content: space-between; background-color: #409EFF;">
        <el-link class="headMain" href="http://localhost:8090/#/clerkName">{{main.qualityManagementSystem}}</el-link>
        <span class="center-text" style="color: white; font-size: 18px;">{{main.goodProductConditions}}</span>
        <el-popover
            placement="top-start"
            title="用户信息"
            width="200"
            trigger="hover">
          <div style="margin-top: 10px">Name：{{useName}}</div>
          <div style="margin-top: 10px">ID:{{useId}}</div>
          <div style="margin-top: 10px" @click="logOut"><el-link>退出</el-link></div>
          <div class="headMain" slot="reference">{{useName}}</div>
        </el-popover>
      </el-header>
      <el-container>
        <el-aside class="el-aside" width="200px" style="height: auto; min-height: 100vh;">
          <el-button
              class="aside-button"
              :style="{
      backgroundColor: activeButton === 2 ? 'blue' : '',
      color: activeButton === 2 ? 'white' : ''
    }"
              @click="buttonMainSelect(2)">
            {{main.resignManagement}}
          </el-button>
          <el-button
              class="aside-button"
              :style="{
      backgroundColor: activeButton === 3 ? 'blue' : '',
      color: activeButton === 3 ? 'white' : ''
    }"
              @click="buttonMainSelect(3)">
            {{main.dressingRoom}}
          </el-button>
          <el-button
              class="aside-button"
              :style="{
      backgroundColor: activeButton === 4 ? 'blue' : '',
      color: activeButton === 4 ? 'white' : ''
    }"
              @click="buttonMainSelect(4)">
            {{main.vacation}}
          </el-button>
          <el-button
              class="aside-button"
              :style="{
      backgroundColor: activeButton === 5 ? 'blue' : '',
      color: activeButton === 5 ? 'white' : ''
    }"
              @click="buttonMainSelect(5)">
            {{main.vacationCalendar}}
          </el-button>
          <el-button
              class="aside-button"
              :style="{
      backgroundColor: activeButton === 6 ? 'blue' : '',
      color: activeButton === 6 ? 'white' : ''
    }"
              @click="buttonMainSelect(6)">
            {{main.organizationChart}}
          </el-button>





        </el-aside>

        <el-container>
          <!--主题设计-->
          <el-main class="el-main" style="height: calc(80vh - 83px);overflow: auto">
            <!-- 员工管理内容 -->
            <div v-if="buttonDoe === -1">
              <el-row :gutter="20">
                <el-col :span="8">
                  <el-button
                      type="primary"
                      @click="openDialog(1, null)"
                      style="margin-bottom: 20px;"
                      v-if="useName === '刘浩'"
                  >
                    Add
                  </el-button>
                </el-col>
                <el-col :span="8">
                  <el-upload
                      action="http://10.255.96.48:3499/russiaEngine/"
                      accept=".xlsx,.xls"
                      :limit="1"
                      :auto-upload="false"
                      :on-change="handleFileChange"
                      :file-list="fileListExcel"
                      style="margin-bottom: 20px"
                      v-if="useName === '刘浩'"
                  >
                    <el-button size="small" style="margin-bottom: 20px;" v-if="useName === '刘浩'">上传EXCEL</el-button>
                  </el-upload>
                </el-col>
              </el-row>
              <div style="margin-bottom: 20px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
                <el-row :gutter="10">
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.shift"
                        placeholder="筛选工号"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in shiftFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.name"
                        placeholder="筛选姓名"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in nameFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.section"
                        placeholder="筛选科室"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in sectionFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.position"
                        placeholder="筛选职位"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in positionFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                </el-row>
                <el-button
                    type="text"
                    @click="clearAllFilters"
                    style="margin-top: 10px;">
                  清除所有筛选
                </el-button>
                <!-- 在筛选工具栏附近添加统计按钮 -->
                <el-col :span="6" v-if="buttonDoe === -1 || buttonDoe === 5">
                  <el-button
                      type="info"
                      @click="showStatistics"
                      icon="el-icon-data-analysis">
                    查看统计
                  </el-button>
                  <el-button
                      type="success"
                      @click="exportStatisticsToExcel"
                      icon="el-icon-download">
                    导出统计
                  </el-button>
                  <el-button
                      type="warning"
                      @click="exportAllData"
                      icon="el-icon-download">
                    下载全部数据
                  </el-button>

                </el-col>

              </div>
              <!-- 数据表格（仅显示需要的列） -->
              <el-table :data="filteredClerkData" style="width: 100%" border>
                <el-table-column prop="employeeNumber" label="工号" width="120"></el-table-column>
                <el-table-column prop="name" label="姓名" width="120"></el-table-column>
                <el-table-column prop="department" label="部门" width="120"></el-table-column>
                <el-table-column prop="section" label="科室" width="120"></el-table-column>
                <el-table-column prop="position" label="职位" width="120"></el-table-column>
                <el-table-column prop="shift" label="班次" width="120"></el-table-column>
                <el-table-column prop="gender" label="Gender" width="80"></el-table-column>
                <el-table-column prop="homeAddress" label="家庭住址" width="180"></el-table-column>
                <el-table-column prop="phone" label="电话" width="150"></el-table-column>
                <el-table-column prop="birthDate" label="生日" width="120"></el-table-column>
                <el-table-column prop="maritalStatus" label="婚否" width="80"></el-table-column>
                <el-table-column prop="children" label="Children" width="80"></el-table-column>
                <el-table-column prop="commute" label="交通方式" width="120"></el-table-column>
                <el-table-column prop="hireDate" label="入职日期" width="120"></el-table-column>
                <el-table-column prop="cabinetKey" label="key" width="120"></el-table-column>
                <!-- 照片列（可选） -->
                <!-- 修改照片列 -->

                <!--编辑按钮-->
                <el-table-column label="编辑" width="120" v-slot:default="scope">
                  <el-link>
                    <i class="el-icon-edit" @click="openDialog(2,scope)"></i>
                  </el-link>
                </el-table-column>
                <el-table-column label="Reason" width="120" v-slot:default="scope">
                  <el-link>
                    <i class="el-icon-delete" @click="openDialog(3,scope)"></i>
                  </el-link>
                </el-table-column>
              </el-table>
              <div style="margin-top: 10px; color: #909399; font-size: 12px;">
                共 {{ filteredClerkData.length }} 条记录
                <span v-if="hasActiveFilters" style="color: #409EFF;">
                </span>
              </div>
            </div>

            <!-- 离职管理内容 -->
            <div v-if="buttonDoe === 2">
              <el-table :data="resignedClerkData" style="width: 100%" border>
                <el-table-column prop="employeeNumber" label="工号" width="120"></el-table-column>
                <el-table-column prop="name" label="姓名" width="120"></el-table-column>
                <el-table-column prop="department" label="部门" width="120"></el-table-column>
                <el-table-column prop="section" label="科室" width="120"></el-table-column>
                <el-table-column prop="position" label="职位" width="120"></el-table-column>
                <el-table-column prop="reason" label="离职原因" width="180"></el-table-column>
                <el-table-column prop="leavingData" label="离职日期" width="120"></el-table-column>
              </el-table>
            </div>
            <!-- 修改柜门显示部分 -->
            <!-- 修改柜门显示部分 -->
            <!-- 修改柜门显示部分 -->
            <div v-if="buttonDoe === 3" class="cabinet-grid">
              <div
                  v-for="cabinet in sortedCabinets"
                  :key="cabinet.id"
                  class="cabinet-item"
                  :class="{ 'occupied': isCabinetOccupied(cabinet.id) }"
              >
                <div class="cabinet-number">{{ cabinet.id }}</div>
                <div>{{ cabinet.cabinetGender }}</div>
                <div>{{ cabinet.cabinetNumber }}</div>
                 <div v-if="getEmployeeByCabinet(cabinet.id)">
       <div> {{ getEmployeeByCabinet(cabinet.id).shift }}</div>

                                               </div>
                <div v-if="isCabinetOccupied(cabinet.id)" class="department-info">
                  {{ getEmployeeByCabinet(cabinet.id)?.name }}
                </div>
                <div v-else class="empty-cabinet">空闲</div>
              </div>
            </div>
            <div v-if="buttonDoe === 4" >
              <!-- 数据表格（仅显示需要的列） -->
              <el-table :data="clerkNameData" style="width: 100%" border>
                <el-table-column prop="employeeNumber" label="工号" width="120"></el-table-column>
                <el-table-column prop="name" label="姓名" width="120"></el-table-column>
                <el-table-column prop="section" label="科室" width="120"></el-table-column>
                <el-table-column prop="position" label="职位" width="120"></el-table-column>


                <el-table-column prop="vacationBeginOne" label="vacationBeginOne" width="120"></el-table-column>
                <el-table-column prop="vacationEndOne" label="vacationEndOne" width="120"></el-table-column>
                <el-table-column prop="vacationBeginTwo" label="vacationBeginTwo" width="120"></el-table-column>
                <el-table-column prop="vacationEndTwo" label="vacationEndTwo" width="120"></el-table-column>
                <el-table-column prop="vacationBeginThree" label="vacationBeginThree" width="120"></el-table-column>
                <el-table-column prop="vacationEndThree" label="vacationEndThree" width="120"></el-table-column>

                <!--编辑按钮-->
                <el-table-column label="编辑" width="120" v-slot:default="scope">
                  <el-link>
                    <i class="el-icon-edit" @click="openDialog(4,scope)"></i>
                  </el-link>
                </el-table-column>

              </el-table>
            </div>
            <div v-if="buttonDoe === 5">
              <!-- 控制工具栏 -->
              <div style="margin-bottom: 20px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
                <el-row :gutter="10">
                  <el-col :span="4">
                    <el-select v-model="selectedYear" placeholder="选择年份" @change="generateDailyData">
                      <el-option
                          v-for="year in yearOptions"
                          :key="year"
                          :label="year + '年'"
                          :value="year">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="4">
                    <el-button
                        type="primary"
                        @click="toggleViewMode"
                        :icon="showDailyView ? 'el-icon-list' : 'el-icon-date'">
                      {{ showDailyView ? '列表视图' : '每日视图' }}
                    </el-button>
                  </el-col>
                  <el-col :span="4">
                    <el-button
                        type="success"
                        @click="exportToExcel"
                        icon="el-icon-download">
                      导出Excel
                    </el-button>
                  </el-col>
                  <el-col :span="12">
                    <div style="float: right;">
                      <span style="margin-right: 10px; color: #606266;">共 {{ dailyData.length }} 名员工</span>
                    </div>
                  </el-col>
                </el-row>
              </div>

              <!-- 筛选工具栏 -->

              <div v-if="!showDailyView" style="margin-bottom: 20px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
                <el-row :gutter="10">
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.shift"
                        placeholder="筛选shift"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in shiftFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.name"
                        placeholder="筛选姓名"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in nameFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.section"
                        placeholder="筛选科室"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in sectionFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-select
                        v-model="filterConditions.position"
                        placeholder="筛选职位"
                        clearable
                        @change="handleManualFilter">
                      <el-option
                          v-for="item in positionFilters"
                          :key="item.value"
                          :label="item.text"
                          :value="item.value">
                      </el-option>
                    </el-select>
                  </el-col>
                </el-row>
                <el-button
                    type="text"
                    @click="clearAllFilters"
                    style="margin-top: 10px;">
                  清除所有筛选
                </el-button>
              </div>

              <!-- 每日数据表格 -->
              <div v-if="showDailyView">
                <div style="margin-bottom: 10px;">
                  <el-alert
                      title="每日假期视图"
                      description="绿色单元格表示员工在该日期休假（1表示休假，0表示工作）"
                      type="info"
                      show-icon
                      :closable="false">
                  </el-alert>
                </div>

                <div class="table-container" style="overflow-x: auto;">
                  <el-table
                      :data="dailyData"
                      border
                      style="width: 100%; min-width: 2000px;"
                      height="600">
                    <el-table-column
                        v-for="header in dailyTableHeaders"
                        :key="header.prop"
                        :prop="header.prop"
                        :label="header.label"
                        :width="header.width"
                        align="center">
                      <template slot-scope="scope">
            <span v-if="header.prop === 'serialNumber' || header.prop === 'name' ||
                       header.prop === 'department' || header.prop === 'section' ||
                       header.prop === 'position'">
              {{ scope.row[header.prop] }}
            </span>
                        <span v-else
                              :style="{
                    color: scope.row[header.prop] === 1 ? '#67C23A' : '#909399',
                    fontWeight: scope.row[header.prop] === 1 ? 'bold' : 'normal'
                  }">
              {{ scope.row[header.prop] }}
            </span>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>

              <!-- 原有列表视图 -->
              <div v-else>
                <el-table :data="filteredClerkData" style="width: 100%" border>
                  <el-table-column prop="employeeNumber" label="工号" width="120"></el-table-column>
                  <el-table-column prop="name" label="姓名" width="120"></el-table-column>
                  <el-table-column prop="section" label="科室" width="120"></el-table-column>
                  <el-table-column prop="position" label="职位" width="120"></el-table-column>
                  <el-table-column prop="vacationBeginOne" label="假期开始1" width="120"></el-table-column>
                  <el-table-column prop="vacationEndOne" label="假期结束1" width="120"></el-table-column>
                  <el-table-column prop="vacationBeginTwo" label="假期开始2" width="120"></el-table-column>
                  <el-table-column prop="vacationEndTwo" label="假期结束2" width="120"></el-table-column>
                  <el-table-column prop="vacationBeginThree" label="假期开始3" width="120"></el-table-column>
                  <el-table-column prop="vacationEndThree" label="假期结束3" width="120"></el-table-column>
                </el-table>

                <div style="margin-top: 10px; color: #909399; font-size: 12px;">
                  共 {{ filteredClerkData.length }} 条记录
                  <span v-if="hasActiveFilters" style="color: #409EFF;">(已筛选)</span>
                </div>
              </div>
            </div>
            <div v-if="buttonDoe === 6" class="organization-chart-container">
              <div class="chart-controls" style="margin-bottom: 20px;">
                <el-row :gutter="10">
                  <el-col :span="6">
                    <el-select v-model="chartType" placeholder="选择图表类型" @change="generateOrgChart">
                      <el-option label="树状图" value="tree"></el-option>
                      <el-option label="组织结构图" value="org"></el-option>
                    </el-select>
                  </el-col>
                  <el-col :span="6">
                    <el-button
                        type="primary"
                        @click="refreshOrgChart"
                        icon="el-icon-refresh">
                      刷新图表
                    </el-button>
                  </el-col>
                  <el-col :span="6">
                    <el-button
                        type="success"
                        @click="exportOrgChart"
                        icon="el-icon-download">
                      导出图片
                    </el-button>
                  </el-col>
                </el-row>
              </div>

              <div v-if="orgChartData.length > 0" class="chart-wrapper">
                <div ref="orgChart" style="width: 100%; height: 600px;"></div>
              </div>
              <div v-else class="empty-chart">
                <el-empty description="暂无组织架构数据"></el-empty>
              </div>
            </div>


          </el-main>
          <el-footer class="el-footer" style="height: 44px; display: flex; align-items: center; justify-content: center;">
            <el-button plain size="mini" @click="languageSelect('chinese')">中  文</el-button>
            <el-button plain size="mini" @click="languageSelect('russian')">Русский язык</el-button>
            <el-button plain size="mini" @click="languageSelect('english')">English</el-button>
          </el-footer>
        </el-container>
      </el-container>
    </el-container>

    <!-- 原有弹窗保持不变 -->
    <el-dialog
        title="添加员工"
        :visible.sync="dialogVisible"
        width="30%">
      <el-form label-width="100px" :model="clerkNameForm">
        <!-- 仅显示需要的字段 -->
        <el-form-item label="姓名">
          <el-input v-model="clerkNameForm.name"></el-input>
        </el-form-item>
        <el-form-item label="部门">
          <el-select v-model="clerkNameForm.department" placeholder="请选择部门">
            <el-option
                v-for="item in departmentOptions"
                :key="item.label"
                :label="item.label"
                :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="科室">
          <el-select v-model="clerkNameForm.section" placeholder="请选择科室" >
            <el-option
                v-for="item in sectionOptions"
                :key="item.value"
                :label="item.label"
                :value="item.label">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="职位">
          <el-select v-model="clerkNameForm.position" placeholder="请选择职位" >
            <el-option
                v-for="item in positionOptions"
                :key="item.value"
                :label="item.label"
                :value="item.label">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="班次">
          <el-select v-model="clerkNameForm.shift" placeholder="请选择班次">
            <el-option
                v-for="item in shiftOptions"
                :key="item.value"
                :label="item.label"
                :value="item.label">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="员工号码">
          <el-input v-model="clerkNameForm.employeeNumber"></el-input>
        </el-form-item>
        <el-form-item label="Gender">
          <el-select v-model="clerkNameForm.gender" placeholder="请选择班次">
            <el-option
                v-for="item in genderOptions"
                :key="item.value"
                :label="item.label"
                :value="item.label">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="家庭住址">
          <el-input v-model="clerkNameForm.homeAddress"></el-input>
        </el-form-item>
        <el-form-item label="电话">
          <el-input v-model="clerkNameForm.phone"></el-input>
        </el-form-item>
        <el-form-item label="生日">
          <el-date-picker
              v-model="clerkNameForm.birthDate"
              type="date"
              placeholder="选择日期"
              value-format="yyyy-MM-dd">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="Married">
          <el-select v-model="clerkNameForm.maritalStatus" placeholder="Married">
            <el-option
                v-for="item in marryOptions"
                :key="item.value"
                :label="item.label"
                :value="item.label">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Children">
          <el-select v-model="clerkNameForm.children" placeholder="孩子数量">
            <el-option
                v-for="item in childrenOptions"
                :key="item.value"
                :label="item.label"
                :value="item.label">
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="交通方式">
          <el-input v-model="clerkNameForm.commute"></el-input>
        </el-form-item>
        <el-form-item label="key">
          <el-input v-model="clerkNameForm.cabinetKey"></el-input>
        </el-form-item>
        <el-form-item label="Glove Size">
          <el-input v-model="clerkNameForm.gloveSize"></el-input>
        </el-form-item>
        <el-form-item label="入职日期">
          <el-date-picker
              v-model="clerkNameForm.hireDate"
              type="date"
              placeholder="选择日期"
              value-format="yyyy-MM-dd">
          </el-date-picker>
        </el-form-item>
        <!-- 照片字段（可选上传组件） -->
        <!-- 照片字段（修改后的上传组件） -->

      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="editorClerkNameOk">确定</el-button>
      </span>
    </el-dialog>

    <!-- 离职原因弹窗 -->
    <el-dialog
        title="Reason Leaving"
        :visible.sync="resignDialogVisible"
        width="30%">
      <el-form label-width="100px" :model="clerkNameForm">
        <el-form-item label="姓名">
          <el-input v-model="clerkNameForm.name" disabled></el-input>
        </el-form-item>
        <el-form-item label="Reason">
          <el-input v-model="clerkNameForm.reason"></el-input>
        </el-form-item>
        <el-form-item label="Leaving Date">
          <el-date-picker
              v-model="clerkNameForm.leavingData"
              type="date"
              placeholder="选择日期"
              value-format="yyyy-MM-dd">
          </el-date-picker>
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="resignDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="editorClerkNameOk">确定</el-button>
      </span>
    </el-dialog>
    <el-dialog
        title="Vacation"
        :visible.sync="vacationVisible"
        width="55%">
      <el-form label-width="140px" :model="clerkNameForm" ref="vacationForm">
        <el-form-item label="姓名">
          <el-input v-model="clerkNameForm.name" disabled></el-input>
        </el-form-item>

        <!-- 第一段假期 -->
        <el-form-item label="第一段假期" required>
          <div style="display: flex; align-items: center; gap: 10px;">
            <span>开始:</span>
            <el-date-picker
                v-model="clerkNameForm.vacationBeginOne"
                type="date"
                placeholder="选择开始日期"
                value-format="yyyy-MM-dd"
                @change="handleBeginOneChange"
                :picker-options="beginOnePickerOptions"
                :class="{ 'error-border': hasDateError(0) }">
            </el-date-picker>
            <span>结束:</span>
            <el-date-picker
                v-model="clerkNameForm.vacationEndOne"
                type="date"
                placeholder="选择结束日期"
                value-format="yyyy-MM-dd"
                :picker-options="endOnePickerOptions"
                @change="validatePeriodRealTime(0)"
                :class="{ 'error-border': hasDateError(0) }">
            </el-date-picker>
            <span v-if="calculateDays(0) > 0" style="color: #409EFF; font-weight: bold;">
          共 {{ calculateDays(0) }} 天
        </span>
            <span v-else-if="clerkNameForm.vacationBeginOne && clerkNameForm.vacationEndOne" style="color: #F56C6C;">
          时间无效
        </span>
          </div>
        </el-form-item>

        <!-- 第二段假期 -->
        <el-form-item label="第二段假期">
          <div style="display: flex; align-items: center; gap: 10px;">
            <span>开始:</span>
            <el-date-picker
                v-model="clerkNameForm.vacationBeginTwo"
                type="date"
                placeholder="选择开始日期"
                value-format="yyyy-MM-dd"
                @change="handleBeginTwoChange"
                :picker-options="beginTwoPickerOptions"
                :class="{ 'error-border': hasDateError(1) }">
            </el-date-picker>
            <span>结束:</span>
            <el-date-picker
                v-model="clerkNameForm.vacationEndTwo"
                type="date"
                placeholder="选择结束日期"
                value-format="yyyy-MM-dd"
                :picker-options="endTwoPickerOptions"
                @change="validatePeriodRealTime(1)"
                :class="{ 'error-border': hasDateError(1) }">
            </el-date-picker>
            <span v-if="calculateDays(1) > 0" style="color: #409EFF; font-weight: bold;">
          共 {{ calculateDays(1) }} 天
        </span>
            <span v-else-if="clerkNameForm.vacationBeginTwo && clerkNameForm.vacationEndTwo" style="color: #F56C6C;">
          时间无效
        </span>
          </div>
        </el-form-item>

        <!-- 第三段假期 -->
        <el-form-item label="第三段假期">
          <div style="display: flex; align-items: center; gap: 10px;">
            <span>开始:</span>
            <el-date-picker
                v-model="clerkNameForm.vacationBeginThree"
                type="date"
                placeholder="选择开始日期"
                value-format="yyyy-MM-dd"
                @change="handleBeginThreeChange"
                :picker-options="beginThreePickerOptions"
                :class="{ 'error-border': hasDateError(2) }">
            </el-date-picker>
            <span>结束:</span>
            <el-date-picker
                v-model="clerkNameForm.vacationEndThree"
                type="date"
                placeholder="选择结束日期"
                value-format="yyyy-MM-dd"
                :picker-options="endThreePickerOptions"
                @change="validatePeriodRealTime(2)"
                :class="{ 'error-border': hasDateError(2) }">
            </el-date-picker>
            <span v-if="calculateDays(2) > 0" style="color: #409EFF; font-weight: bold;">
          共 {{ calculateDays(2) }} 天
        </span>
            <span v-else-if="clerkNameForm.vacationBeginThree && clerkNameForm.vacationEndThree" style="color: #F56C6C;">
          时间无效
        </span>
          </div>
        </el-form-item>

        <!-- 总天数统计 -->
        <el-alert
            v-if="totalVacationDays > 0"
            :title="`总假期天数: ${totalVacationDays} 天`"
            type="success"
            :description="getVacationPeriodsDescription()"
            show-icon
            style="margin-bottom: 20px;">
        </el-alert>

        <!-- 显示验证提示 -->
        <el-alert
            v-if="showValidationWarning"
            title="提示"
            type="warning"
            description="请确保：1. 开始时间不晚于结束时间；2. 各假期时间段没有交叉重叠"
            show-icon
            style="margin-bottom: 20px;">
        </el-alert>
      </el-form>

      <span slot="footer" class="dialog-footer">
    <el-button @click="vacationVisible = false">取消</el-button>
    <el-button type="primary" @click="editorClerkNameOk">确定</el-button>
  </span>
    </el-dialog>
  </div>
</template>

<script>
import _ from "lodash";
import * as XLSX from 'xlsx'; // 添加这行导入
import * as echarts from 'echarts'; // 引入 ECharts

export default {
  name: "suspectProductGuo",
  data() {
    return {




      chartType: 'tree',
      orgChartData: [],
      orgChartInstance: null,
      operatorListFile:null,
      operatorListImageUrl:null,
      selectedYear: 2025,
      yearOptions: [2025,2026,2027,2028],
      dailyData: [],
      dailyHeaders: [],
      showDailyView: false, // 控制显示模式
      fileListExcel:[],
      filterConditions: {
        shift: null,
        name: null,
        section: null,
        position: null
      },
      // 日期选择器配置
      beginOnePickerOptions: {
        disabledDate: () => {
          return false; // 第一段开始日期不受限制
        }
      },
      endOnePickerOptions: {
        disabledDate: (time) => {
          if (this.clerkNameForm.vacationBeginOne) {
            const beginDate = new Date(this.clerkNameForm.vacationBeginOne);
            return time.getTime() < beginDate.getTime();
          }
          return false;
        }
      },
      beginTwoPickerOptions: {
        disabledDate: () => {
          return false; // 第二段开始日期不受限制
        }
      },
      endTwoPickerOptions: {
        disabledDate: (time) => {
          if (this.clerkNameForm.vacationBeginTwo) {
            const beginDate = new Date(this.clerkNameForm.vacationBeginTwo);
            return time.getTime() < beginDate.getTime();
          }
          return false;
        }
      },
      beginThreePickerOptions: {
        disabledDate: () => {
          return false; // 第三段开始日期不受限制
        }
      },
      endThreePickerOptions: {
        disabledDate: (time) => {
          if (this.clerkNameForm.vacationBeginThree) {
            const beginDate = new Date(this.clerkNameForm.vacationBeginThree);
            return time.getTime() < beginDate.getTime();
          }
          return false;
        }
      },
      dateErrors: [false, false, false],
      cabinets: [],

      // 当前选中的按钮（2 或 3）
      activeButton: -1,
      // 用户权限相关的变量
      useName: '', // 用户名称
      useId: '', // 用户编号
      usePower: '', // 用户权限
      languageS: 'chinese', // 用户登录后默认为中文

      // 按钮样式控制
      buttonDoe: -1, // 默认不显示任何特殊内容
      buttonBackColor2: '',
      buttonColor2: '',

      // 切换语言，页面变量
      main: {
        qualityManagementSystem: 'Russian Engine HRMS',
        goodProductConditions: 'Russia personnel information',
        resignManagement: 'Resign Management', // 离职管理
        dressingRoom: 'DressingRoom', //
        vacation:'Vacation',
        vacationCalendar:'Vacation Calendar',
        organizationChart: 'Organization Chart' // 新增
      },

      // 班次选项
      shiftOptions: [
        { value: 'Day', label: 'DAY' },
        { value: 'A', label: 'A' },
        { value: 'B', label: 'B' }
      ],
      childrenOptions: [
        { value: '1', label: '1' },
        { value: '2', label: '2' },
        { value: '3', label: '3' },
        { value: '4', label: '4' },
        { value: '5', label: '5' },
        { value: '6', label: '6' },
      ],
      genderOptions: [
        { value: 'Man', label: 'Man' },
        { value: 'Women', label: 'Women' }
      ],
      marryOptions:[
        { value: 'Yes', label: 'Yes' },
        { value: 'No', label: 'No' }
      ],
      // 部门选项
      departmentOptions: [
        // 制造部门 (Manufacturing Department of ES)
        {
          value: 'Manufacturing Department of ES',
          label: 'Manufacturing Department of ES',
          sections: [
            {
              value: 'Manufacturing Department of ES',
              label: 'Manufacturing Department of ES',
              positions: [
                { value: 'Deputy Department Director', label: 'Deputy Department Director' },
                { value: 'Safety Specialist', label: 'Safety Specialist' },
                { value: 'Specialist TPS', label: 'Specialist TPS' }
              ]
            },
            // 发动机装配车间 (Engine Assembly Shop)
            {
              value: 'Engine Assembly Shop',
              label: 'Engine Assembly Shop',
              positions: [
                { value: 'Deputy shop manager', label: 'Deputy shop manager' },
                { value: 'Group leader', label: 'Group leader' },
                { value: 'Operator', label: 'Operator' },
                { value: 'Freeman', label: 'Freeman' },
                { value: 'Shift leader', label: 'Shift leader' },
                { value: 'Statistics specialist', label: 'Statistics specialist' },
                { value: 'Team leader', label: 'Team leader' }
              ]
            },
            // 机械车间 (Machine Shop)
            {
              value: 'A2',
              label: 'Machine Shop',
              positions: [
                { value: 'Deputy Shop Manager', label: 'Deputy Shop Manager' },
                { value: 'Shift Leader', label: 'Shift Leader' },
                { value: 'Statistics specialist', label: 'Statistics specialist' },
                { value: 'Team leader', label: 'Team leader' },
                { value: 'Freeman', label: 'Freeman' },
                { value: 'Operator MS', label: 'Operator MS' }
              ]
            },
            // 生产技术科 (Production Technology Section)
            {
              value: 'Production Technology Section',
              label: 'Production Technology Section',
              positions: [
                { value: 'Deputy Manager Section', label: 'Deputy Manager Section' },
                { value: 'Tooling Engineer', label: 'Tooling Engineer' },
                { value: 'Fixture Engineer', label: 'Fixture Engineer' },
                { value: 'Line Engineer', label: 'Line Engineer' },
                { value: 'Lead Line Engineer', label: 'Lead Line Engineer' },
                { value: 'Process Engineer PT', label: 'Process Engineer PT' },
                { value: 'Production Quality Control Engineer', label: 'Production Quality Control Engineer' }
              ]
            }
          ]
        },

        // 总务组 (General Affairs Group of ES)
        {
          value: 'General Affairs Group of ES',
          label: 'General Affairs Group of ES',
          sections: [
            {
              value: 'Engine GA group',
              label: 'Engine GA group',
              positions: [
                { value: 'Economist', label: 'Economist' },
                { value: 'Leading Administrative specialist', label: 'Leading Administrative specialist' },
                { value: 'Training Coordinator', label: 'Training Coordinator' }
              ]
            }
          ]
        },

        // 生产管理及物流科 (Production Management and Logistics Section of ES)
        {
          value: 'Production Management and Logistics Section of ES',
          label: 'Production Management and Logistics Section of ES',
          sections: [
            {
              value: 'Logistics Section',
              label: 'Logistics Section',
              positions: [
                { value: 'Deputy Manager Section', label: 'Deputy Manager Section' },
                { value: 'Group leader', label: 'Group leader' },
                { value: 'Procurement specialist', label: 'Procurement specialist' },
                { value: 'Loader driver', label: 'Loader driver' },
                { value: 'Freeman', label: 'Freeman' },
                { value: 'Picker', label: 'Picker' },
                { value: 'Team leader', label: 'Team leader' },
                { value: 'Warehousing and document management specialist', label: 'Warehousing and document management specialist' },
                { value: 'Storekeeper', label: 'Storekeeper' },
                { value: 'Production Data specialist', label: 'Production Data specialist' }
              ]
            },
            {
              value: 'Production Planning Group',
              label: 'Production Planning Group',
              positions: [
                { value: 'Planning Specialist', label: 'Planning Specialist' }
              ]
            }
          ]
        },

        // 质量技术部 (Quality and Technology Department of ES)
        {
          value: 'D',
          label: 'Quality and Technology Department of ES',
          sections: [
            {
              value: 'D0',
              label: 'Quality and Technology Department of ES',
              positions: [
                { value: 'Deputy Department Director', label: 'Deputy Department Director' }
              ]
            },
            {
              value: 'Quality Management Section',
              label: 'Quality Management Section',
              positions: [
                { value: 'Deputy Manager Section', label: 'Deputy Manager Section' },
                { value: 'Group leader', label: 'Group leader' },
                { value: 'Measurement Engineer', label: 'Measurement Engineer' },
                { value: 'Quality Engineer', label: 'Quality Engineer' },
                { value: 'Quality Management System Specialist', label: 'Quality Management System Specialist' },
                { value: 'Statistics specialist', label: 'Statistics specialist' },
                { value: 'Team leader', label: 'Team leader' },
                { value: 'Technical quality controller', label: 'Technical quality controller' },
                { value: 'Product Technologist Engineer', label: 'Product Technologist Engineer' }
              ]
            },
            {
              value: 'Quality Technology Section',
              label: 'Quality Technology Section',
              positions: [
                { value: 'Deputy Manager Section', label: 'Deputy Manager Section' },
                { value: 'Group leader', label: 'Group leader' },
                { value: 'Process Engineer' , label: 'Process Engineer' },
                { value: 'Product Technologist Engineer', label: 'Product Technologist Engineer' }
              ]
            }
          ]
        }
      ],
      sectionOptions: [], // 动态生成的科室选项
      positionOptions: [], // 动态生成的职位选项

      // 员工管理相关数据
      dialogVisible: false,
      resignDialogVisible: false,
      vacationVisible:false,
      clerkNameData: [], // 在职员工数据
      resignedClerkData: [], // 离职员工数据

      clerkNameForm: {
        id: '',
        create_: '',
        update_time: '',
        creator: '',
        process_status: '',
        sys_update_user: '',
        sys_audit_user: '',
        sys_audit_time: '',
        sys_deleted: 0,
        serialNumber: '',
        name: '',        // 增加姓名字段
        department: '',  // 增加部门字段
        section: '',             // 科室
        position: '',            // 职位
        shift: '',               // 班次
        employeeNumber: '',     // 员工号码
        gender: '',              // 性别
        homeAddress: '',        // 家庭住址
        phone: '',               // 电话
        birthDate: '',          // 生日（改用日期对象）
        maritalStatus: '',      // 婚否
        children: '',            // 孩子
        commute: '',             // 交通方式
        hireDate: '',           // 入职日期（改用日期对象）
        photo: '',
        reason: '',
        leavingData: '', // 离职日期
        cabinetKey:'',
        gloveSize:'',
        vacationBeginOne:'',
        vacationEndOne:'',
        vacationBeginTwo:'',
        vacationEndTwo:'',
        vacationBeginThree:'',
        vacationEndThree:''
      },
      clerkNameDoe: 0,
      clerkNameScope: null,
    }
  },
  computed: {



    sortedCabinets() {
      return [...this.cabinets].sort((a, b) => {
        // 尝试将id转换为数字
        const numA = parseInt(a.id, 10);
        const numB = parseInt(b.id, 10);

        // 如果都是有效数字，按数字排序
        if (!isNaN(numA) && !isNaN(numB)) {
          return numA - numB;
        }

        // 否则按字符串排序
        return a.id.localeCompare(b.id);
      });
    },
    // 其他计算属性...

    dailyTableHeaders() {
      const headers = [
        { prop: 'employeeNumber', label: '工号', width: '100' },
        { prop: 'name', label: '姓名', width: '100' },
        { prop: 'department', label: '部门', width: '120' },
        { prop: 'section', label: '科室', width: '120' },
        { prop: 'position', label: '职位', width: '120' }
      ];

      // 添加日期列
      this.dailyHeaders.forEach(date => {
        headers.push({
          prop: date,
          label: this.formatDateHeader(date),
          width: '60'
        });
      });

      return headers;
    },
    shiftFilters() {
      return this.generateFilters('shift');
    },

    nameFilters() {
      return this.generateFilters('name');
    },

    sectionFilters() {
      return this.generateFilters('section');
    },

    positionFilters() {
      return this.generateFilters('position');
    },

    // Fixed: No side effects and no undefined 'result'
    filteredClerkData() {
      // First, get the base data without modifying component state
      const baseData = this.clerkNameData.filter(item =>
          item.reason == null || item.reason === ''
      );

      // Then check if the filtered data is empty
      if (!baseData || baseData.length === 0) {
        return [];
      }

      return baseData.filter(item => {
        // 检查工号筛选
        if (this.filterConditions.shift &&
            item.shift !== this.filterConditions.shift) {
          return false;
        }

        // 检查姓名筛选
        if (this.filterConditions.name &&
            item.name !== this.filterConditions.name) {
          return false;
        }

        // 检查科室筛选
        if (this.filterConditions.section &&
            item.section !== this.filterConditions.section) {
          return false;
        }

        // 检查职位筛选
        if (this.filterConditions.position &&
            item.position !== this.filterConditions.position) {
          return false;
        }

        return true;
      });
    },

    hasActiveFilters() {
      return Object.values(this.filterConditions).some(condition => condition !== null);
    },

    showValidationWarning() {
      return this.clerkNameForm.vacationBeginOne || this.clerkNameForm.vacationEndOne ||
          this.clerkNameForm.vacationBeginTwo || this.clerkNameForm.vacationEndTwo ||
          this.clerkNameForm.vacationBeginThree || this.clerkNameForm.vacationEndThree;
    },

    totalVacationDays() {
      let total = 0;
      for (let i = 0; i < 3; i++) {
        total += this.calculateDays(i);
      }
      return total;
    }
  },
  methods: {
    generateOrgChart() {
      console.log('开始生成组织架构图...');

      // 检查员工数据
      console.log('员工数据:', this.clerkNameData);

      // 构建组织数据
      const orgData = this.buildOrganizationData();
      console.log('组织架构数据:', orgData);

      this.orgChartData = orgData;

      if (orgData.length === 0) {
        console.warn('组织架构数据为空，无法生成图表');
        this.$message.warning('没有找到有效的组织架构数据');
        return;
      }

      // 检查DOM元素
      const chartDom = this.$refs.orgChart;
      if (!chartDom) {
        console.error('未找到图表容器DOM元素');
        return;
      }
      console.log('图表容器找到:', chartDom);

      // 销毁旧实例
      if (this.orgChartInstance) {
        this.orgChartInstance.dispose();
      }

      // 初始化图表
      this.orgChartInstance = echarts.init(chartDom);

      const option = this.chartType === 'tree'
          ? this.getTreeChartOption(orgData)
          : this.getOrgChartOption(orgData);

      console.log('ECharts配置:', option);

      this.orgChartInstance.setOption(option);

      // 检查图表是否成功渲染
      setTimeout(() => {
        if (!this.orgChartInstance || !this.orgChartInstance.getOption()) {
          console.error('图表渲染失败');
          this.$message.error('图表渲染失败，请检查数据格式');
        } else {
          console.log('图表渲染成功');
        }
      }, 1000);

      // 响应窗口大小变化
      window.addEventListener('resize', () => {
        this.orgChartInstance && this.orgChartInstance.resize();
      });
    },

    buildOrganizationData() {
      const departments = {};

      // 过滤在职员工
      const activeEmployees = this.clerkNameData.filter(emp =>
          !emp.reason || emp.reason === ''
      );

      // 按部门、科室、职位构建层级结构
      activeEmployees.forEach(emp => {
        const dept = emp.department || '未分配部门';
        const section = emp.section || '未分配科室';
        const position = emp.position || '未分配职位';
        const name = emp.name || '未知姓名';
        const employeeNumber = emp.employeeNumber || '';

        if (!departments[dept]) {
          departments[dept] = {
            name: dept,
            value: 0,
            children: {}
          };
        }

        if (!departments[dept].children[section]) {
          departments[dept].children[section] = {
            name: section,
            value: 0,
            children: {}
          };
        }

        if (!departments[dept].children[section].children[position]) {
          departments[dept].children[section].children[position] = {
            name: position,
            value: 0,
            children: []
          };
        }

        // 添加员工到职位下
        departments[dept].children[section].children[position].children.push({
          name: `${name} (${employeeNumber})`,
          value: 1,
          itemStyle: {
            color: '#91cc75'
          }
        });

        // 计数
        departments[dept].children[section].children[position].value++;
        departments[dept].children[section].value++;
        departments[dept].value++;
      });

      // 转换为 ECharts 需要的格式
      return this.convertToEChartsData(departments);
    },

    convertToEChartsData(departments) {
      const result = {
        name: '组织架构',
        children: []
      };

      Object.values(departments).forEach(dept => {
        const deptNode = {
          name: `${dept.name} (${dept.value})`,
          value: dept.value,
          itemStyle: {
            color: '#5470c6'
          },
          children: []
        };

        Object.values(dept.children).forEach(section => {
          const sectionNode = {
            name: `${section.name} (${section.value})`,
            value: section.value,
            itemStyle: {
              color: '#91cc75'
            },
            children: []
          };

          Object.values(section.children).forEach(position => {
            const positionNode = {
              name: `${position.name} (${position.value})`,
              value: position.value,
              itemStyle: {
                color: '#fac858'
              },
              children: position.children
            };

            sectionNode.children.push(positionNode);
          });

          deptNode.children.push(sectionNode);
        });

        result.children.push(deptNode);
      });

      return [result];
    },

    getTreeChartOption(data) {
      return {
        tooltip: {
          trigger: 'item',
          triggerOn: 'mousemove',
          formatter: function (params) {
            return `${params.name}<br/>人数: ${params.value}`;
          }
        },
        series: [
          {
            type: 'tree',
            data: data,
            top: '1%',
            left: '7%',
            bottom: '1%',
            right: '20%',
            symbolSize: 7,
            label: {
              position: 'left',
              verticalAlign: 'middle',
              align: 'right',
              fontSize: 12,
              formatter: function (params) {
                return params.name;
              }
            },
            leaves: {
              label: {
                position: 'right',
                verticalAlign: 'middle',
                align: 'left'
              }
            },
            emphasis: {
              focus: 'descendant'
            },
            expandAndCollapse: true,
            animationDuration: 550,
            animationDurationUpdate: 750
          }
        ]
      };
    },

    getOrgChartOption(data) {
      return {
        tooltip: {
          trigger: 'item',
          formatter: function (params) {
            return `${params.name}<br/>人数: ${params.value}`;
          }
        },
        series: [
          {
            type: 'tree',
            data: data,
            layout: 'orthogonal',
            orient: 'vertical',
            top: '10px',
            left: '10px',
            bottom: '10px',
            right: '10px',
            symbolSize: 10,
            label: {
              position: 'top',
              rotate: -90,
              verticalAlign: 'middle',
              align: 'right',
              fontSize: 10
            },
            leaves: {
              label: {
                position: 'bottom',
                rotate: -90,
                verticalAlign: 'middle',
                align: 'left'
              }
            },
            emphasis: {
              focus: 'descendant'
            },
            expandAndCollapse: true,
            animationDuration: 550,
            animationDurationUpdate: 750
          }
        ]
      };
    },

    refreshOrgChart() {
      this.generateOrgChart();
      this.$message.success('组织架构图已刷新');
    },

    exportOrgChart() {
      if (!this.orgChartInstance) {
        this.$message.warning('请先生成组织架构图');
        return;
      }

      const chartDataURL = this.orgChartInstance.getDataURL({
        type: 'png',
        pixelRatio: 2,
        backgroundColor: '#fff'
      });

      const link = document.createElement('a');
      link.href = chartDataURL;
      link.download = `组织架构图_${new Date().toISOString().split('T')[0]}.png`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      this.$message.success('组织架构图导出成功');
    },

    // 修改按钮选择方法，添加组织架构图处理
    buttonMainSelect(doe) {
      this.buttonDoe = doe;
      this.activeButton = doe;

      if (doe === 2 || doe === 3) {
        this.queryResignedClerkData();
      } else if (doe === 6) {
        // 组织架构图
        this.$nextTick(() => {
          this.generateOrgChart();
        });
      }
    },
// 导出所有员工数据到Excel
    exportAllData() {
      if (!this.clerkNameData || this.clerkNameData.length === 0) {
        this.$message.warning('没有可导出的数据');
        return;
      }

      // 准备导出数据（包含所有字段）
      const exportData = this.clerkNameData.map(employee => {
        return {
          '工号': employee.serialNumber || '',
          '姓名': employee.name || '',
          '部门': employee.department || '',
          '科室': employee.section || '',
          '职位': employee.position || '',
          '班次': employee.shift || '',
          '员工号码': employee.employeeNumber || '',
          '性别': employee.gender || '',
          '家庭住址': employee.homeAddress || '',
          '电话': employee.phone || '',
          '生日': employee.birthDate || '',
          '婚否': employee.maritalStatus || '',
          '孩子数量': employee.children || '',
          '交通方式': employee.commute || '',
          '入职日期': employee.hireDate || '',
          '柜门钥匙': employee.cabinetKey || '',
          '手套尺寸': employee.gloveSize || '',
          '离职原因': employee.reason || '',
          '离职日期': employee.leavingData || '',
          // 假期信息
          '第一段假期开始': employee.vacationBeginOne || '',
          '第一段假期结束': employee.vacationEndOne || '',
          '第二段假期开始': employee.vacationBeginTwo || '',
          '第二段假期结束': employee.vacationEndTwo || '',
          '第三段假期开始': employee.vacationBeginThree || '',
          '第三段假期结束': employee.vacationEndThree || ''
        };
      });

      // 创建工作簿
      const wb = XLSX.utils.book_new();

      // 创建工作表
      const ws = XLSX.utils.json_to_sheet(exportData);

      // 将工作表添加到工作簿
      XLSX.utils.book_append_sheet(wb, ws, '员工数据');

      // 生成Excel文件并下载
      const fileName = `员工数据_${new Date().toISOString().split('T')[0]}.xlsx`;
      XLSX.writeFile(wb, fileName);

      this.$message.success('数据导出成功');
    },


    //生成唯一标识码的函数（利用时间戳和随机数）
    generateUniqueId() {
      return Date.now().toString() + Math.random().toString(36).slice(2, 11);
    },
    handleAvatarSuccess(file) {
      this.operatorListImageUrl = URL.createObjectURL(file.raw);
      this.operatorListFile=file
      console.log(this.operatorListFile)
    },
    beforeAvatarUpload(file) {
      // 允许的MIME类型列表
      const allowedTypes = ['image/jpeg', 'image/png', 'image/jpg'];

      // 修正后的类型检查（使用数组includes）
      const isAllowedType = allowedTypes.includes(file.type);

      // 大小检查保持不变
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isAllowedType) {
        this.$message.error('只能上传 JPG/PNG 格式的图片!');
      }

      return isAllowedType && isLt2M;
    },

    // 检查柜门是否被占用
    isCabinetOccupied(cabinetNumber) {
      if (!cabinetNumber || !this.clerkNameData || this.clerkNameData.length === 0) {
        return false;
      }

      // 将柜门号转换为字符串进行比较
      const cabinetNumStr = cabinetNumber.toString().trim();

      return this.clerkNameData.some(emp => {
        if (!emp || emp.reason) {
          return false; // 有离职原因的不算占用
        }

        // 处理员工柜门钥匙字段
        const empCabinetKey = emp.cabinetKey ? emp.cabinetKey.toString().trim() : '';

        return empCabinetKey === cabinetNumStr;
      });
    },

    // 根据柜门号获取员工信息
    getEmployeeByCabinet(cabinetNumber) {
      if (!cabinetNumber || !this.clerkNameData || this.clerkNameData.length === 0) {
        return null;
      }

      // 将柜门号转换为字符串进行比较
      const cabinetNumStr = cabinetNumber.toString().trim();

      return this.clerkNameData.find(emp => {
        if (!emp || emp.reason) {
          return false;
        }

        const empCabinetKey = emp.cabinetKey ? emp.cabinetKey.toString().trim() : '';
        return empCabinetKey === cabinetNumStr;
      });
    },

    // 添加根据柜门号获取员工信息的方

      // 其他方法保持不变..
    // 修改 fetchCabinets 方法，直接设置 cabinets 数据
    async fetchCabinets() {
      try {
        const result = await this.$request.post('/queryCabinetKey');
        if (result.code === 401) {
          this.$router.push('UserLogin');
          this.$message.error("您未登录，请登录");
          this.cabinets = [];
        } else {
          console.log('获取到的柜门数据:', result.data); // 添加这行调试
          this.cabinets = Array.isArray(result.data) ? result.data : [];
        }
      } catch (error) {
        console.error('API请求失败:', error);
        this.$message.error('网络连接失败，请检查服务器状态');
        this.cabinets = [];
      }
    },

// 临时测试方法 - 用于验证前端显示

// 统计各部门、科室、职位人数
    generateDepartmentStatistics() {
      const statistics = {};

      // 过滤掉reason有值的员工（离职员工）
      const activeEmployees = this.clerkNameData.filter(employee =>
          !employee.reason || employee.reason.trim() === ''
      );

      // 按部门、科室、职位进行统计
      activeEmployees.forEach(employee => {
        const { department, section, position } = employee;

        // 初始化部门
        if (!statistics[department]) {
          statistics[department] = {
            total: 0,
            sections: {}
          };
        }

        // 初始化科室
        if (!statistics[department].sections[section]) {
          statistics[department].sections[section] = {
            total: 0,
            positions: {}
          };
        }

        // 初始化职位
        if (!statistics[department].sections[section].positions[position]) {
          statistics[department].sections[section].positions[position] = 0;
        }

        // 计数
        statistics[department].total++;
        statistics[department].sections[section].total++;
        statistics[department].sections[section].positions[position]++;
      });

      return statistics;
    },

// 显示统计结果
    showStatistics() {
      const stats = this.generateDepartmentStatistics();

      // 创建统计弹窗
      this.$msgbox({
        title: '部门人员统计',
        message: this.renderStatisticsHTML(stats),
        dangerouslyUseHTMLString: true,
        customClass: 'statistics-modal',
        showConfirmButton: true,
        confirmButtonText: '关闭',
        showCancelButton: false,
        closeOnClickModal: true,
        width: '800px'
      });
    },

// 渲染统计HTML
    renderStatisticsHTML(stats) {
      let html = '<div class="statistics-container">';

      // 总人数
      const totalEmployees = Object.values(stats).reduce((total, dept) => total + dept.total, 0);
      html += `<div class="total-count">总在职人数: <strong>${totalEmployees}</strong> 人</div>`;

      // 各部门统计
      Object.keys(stats).forEach(deptName => {
        const dept = stats[deptName];
        html += `
      <div class="department-section">
        <div class="department-header">
          <h3>${deptName}</h3>
          <span class="count-badge">${dept.total} 人</span>
        </div>
    `;

        // 各科室统计
        Object.keys(dept.sections).forEach(sectionName => {
          const section = dept.sections[sectionName];
          html += `
        <div class="section-item">
          <div class="section-header">
            <strong>${sectionName}</strong>
            <span class="count-badge">${section.total} 人</span>
          </div>
          <div class="positions-list">
      `;

          // 各职位统计
          Object.keys(section.positions).forEach(positionName => {
            const count = section.positions[positionName];
            html += `
          <div class="position-item">
            <span class="position-name">${positionName}</span>
            <span class="position-count">${count} 人</span>
          </div>
        `;
          });

          html += `</div></div>`;
        });

        html += `</div>`;
      });

      html += '</div>';
      return html;
    },

// 导出统计到Excel
    exportStatisticsToExcel() {
      const stats = this.generateDepartmentStatistics();
      const wb = XLSX.utils.book_new();

      // 准备数据
      const excelData = [];

      // 添加表头
      excelData.push(['部门', '科室', '职位', '人数']);

      // 填充数据
      Object.keys(stats).forEach(deptName => {
        const dept = stats[deptName];

        Object.keys(dept.sections).forEach(sectionName => {
          const section = dept.sections[sectionName];

          Object.keys(section.positions).forEach(positionName => {
            const count = section.positions[positionName];
            excelData.push([deptName, sectionName, positionName, count]);
          });

          // 添加科室小计
          excelData.push([deptName, sectionName, '小计', section.total]);
        });

        // 添加部门小计
        excelData.push([deptName, '', '部门小计', dept.total]);
      });

      // 添加总计
      const total = Object.values(stats).reduce((sum, dept) => sum + dept.total, 0);
      excelData.push(['', '', '总计', total]);

      // 创建工作表
      const ws = XLSX.utils.aoa_to_sheet(excelData);
      XLSX.utils.book_append_sheet(wb, ws, '部门人员统计');

      // 下载文件
      const fileName = `部门人员统计_${new Date().toISOString().split('T')[0]}.xlsx`;
      XLSX.writeFile(wb, fileName);

      this.$message.success('统计导出成功');
    },
    // ... 其他现有方法保持不变

    // 切换显示模式
    toggleViewMode() {
      this.showDailyView = !this.showDailyView;
      if (this.showDailyView) {
        this.generateDailyData();
      }
    },

    // 生成每日数据（对应 Excel 宏的功能）
    generateDailyData() {
      const year = this.selectedYear;
      const startDate = new Date(year, 0, 1); // 1月1日
      const endDate = new Date(year, 11, 31); // 12月31日

      // 生成日期表头
      this.dailyHeaders = [];
      const currentDate = new Date(startDate);
      while (currentDate <= endDate) {
        const dateStr = this.formatDate(currentDate);
        this.dailyHeaders.push(dateStr);
        currentDate.setDate(currentDate.getDate() + 1);
      }

      // 生成每日数据
      this.dailyData = this.filteredClerkData.map(employee => {
        const rowData = {
          serialNumber: employee.serialNumber,
          name: employee.name,
          department: employee.department,
          section: employee.section,
          position: employee.position
        };

        // 获取员工的假期时间段
        const vacationPeriods = this.getEmployeeVacationPeriods(employee);

        // 为每一天设置值
        this.dailyHeaders.forEach(dateStr => {
          const currentDate = new Date(dateStr);
          const isOnVacation = this.isDateInVacationPeriods(currentDate, vacationPeriods);
          rowData[dateStr] = isOnVacation ? 1 : 0;
        });

        return rowData;
      });
    },

    // 获取员工的假期时间段
    getEmployeeVacationPeriods(employee) {
      const periods = [];

      // 第一段假期
      if (employee.vacationBeginOne && employee.vacationEndOne) {
        periods.push({
          start: new Date(employee.vacationBeginOne),
          end: new Date(employee.vacationEndOne)
        });
      }

      // 第二段假期
      if (employee.vacationBeginTwo && employee.vacationEndTwo) {
        periods.push({
          start: new Date(employee.vacationBeginTwo),
          end: new Date(employee.vacationEndTwo)
        });
      }

      // 第三段假期
      if (employee.vacationBeginThree && employee.vacationEndThree) {
        periods.push({
          start: new Date(employee.vacationBeginThree),
          end: new Date(employee.vacationEndThree)
        });
      }

      return periods;
    },

    // 检查日期是否在假期时间段内
    isDateInVacationPeriods(date, periods) {
      return periods.some(period => {
        return date >= period.start && date <= period.end;
      });
    },

    // 格式化日期为 YYYY-MM-DD
    formatDate(date) {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      return `${year}-${month}-${day}`;
    },

    // 格式化日期表头（显示为 MM-DD）
    formatDateHeader(dateStr) {
      const date = new Date(dateStr);
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      return `${month}-${day}`;
    },

    // 导出到 Excel
    exportToExcel() {
      try {
        // 创建工作簿
        const wb = XLSX.utils.book_new();

        // 准备导出数据
        const exportData = this.dailyData.map(row => {
          const exportRow = {
            '工号': row.serialNumber,
            '姓名': row.name,
            '部门': row.department,
            '科室': row.section,
            '职位': row.position
          };

          // 添加每日数据
          this.dailyHeaders.forEach(dateStr => {
            const header = this.formatDateHeader(dateStr);
            exportRow[header] = row[dateStr];
          });

          return exportRow;
        });

        // 创建工作表
        const ws = XLSX.utils.json_to_sheet(exportData);

        // 将工作表添加到工作簿
        XLSX.utils.book_append_sheet(wb, ws, '每日假期数据');

        // 生成 Excel 文件并下载
        const fileName = `员工假期数据_${this.selectedYear}.xlsx`;
        XLSX.writeFile(wb, fileName);

        this.$message.success('导出成功');
      } catch (error) {
        console.error('导出失败:', error);
        this.$message.error('导出失败');
      }
    },

    // 获取月份数据统计
    getMonthStatistics(month) {
      const monthData = this.dailyData.map(employee => {
        const monthStart = new Date(this.selectedYear, month - 1, 1);
        const monthEnd = new Date(this.selectedYear, month, 0);
        let vacationDays = 0;

        for (let date = new Date(monthStart); date <= monthEnd; date.setDate(date.getDate() + 1)) {
          const dateStr = this.formatDate(date);
          if (employee[dateStr] === 1) {
            vacationDays++;
          }
        }

        return {
          name: employee.name,
          serialNumber: employee.serialNumber,
          vacationDays: vacationDays
        };
      });

      return monthData.filter(emp => emp.vacationDays > 0)
          .sort((a, b) => b.vacationDays - a.vacationDays);
    },

    handleFileChange(file) {
      const fileToRead = file.raw || null;
      if (!fileToRead) {
        this.$message.warning('请选择有效的文件');
        return;
      }

      if (!fileToRead.name.endsWith('.xlsx') && !fileToRead.name.endsWith('.xls')) {
        this.$message.error('请选择Excel文件（.xlsx 或 .xls 格式）');
        return;
      }

      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: 'array' });
          const firstSheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[firstSheetName];
          const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

          if (jsonData.length <= 1) {
            this.$message.error('Excel文件为空或只有表头');
            return;
          }

          const importedEmployees = [];

          // 从第二行开始读取数据
          for (let i = 1; i < jsonData.length; i++) {
            const row = jsonData[i];
            if (!row || row.length === 0 || !row[0]) continue;

            const uuid = this.generateUUIDv4();

            // 创建员工对象，根据Excel表头顺序映射字段
            const employee = {
              id: uuid,
              create_time: new Date().toISOString(),
              update_time: new Date().toISOString(),
              creator: this.useName,
              process_status: 'active',
              sys_update_user: this.useName,
              sys_audit_user: '',
              sys_audit_time: '',
              sys_deleted: 0,

              // 基本信息 - 按照Excel表头顺序映射
              serialNumber: row[0] ? String(row[0]).trim() : '', // Employee ID
              name: row[1] ? String(row[1]).trim() : '',         // Name
              department: row[2] ? String(row[2]).trim() : '',   // Department
              section: row[3] ? String(row[3]).trim() : '',      // Section
              position: row[4] ? String(row[4]).trim() : '',     // Position
              shift: row[5] ? String(row[5]).trim() : '',        // Shift
              employeeNumber: row[6] ? String(row[6]).trim() : '', // Employee Number
              gender: row[7] ? String(row[7]).trim() : '',       // Gender
              homeAddress: row[8] ? String(row[8]).trim() : '',  // Home Address
              phone: row[9] ? String(row[9]).trim() : '',        // Phone
              birthDate: this.formatExcelDate(row[10]),         // Birth Date
              maritalStatus: row[11] ? String(row[11]).trim() : '', // Marital Status
              children: row[12] ? String(row[12]).trim() : '',   // Children
              commute: row[13] ? String(row[13]).trim() : '',    // Commute Method
              hireDate: this.formatExcelDate(row[14]),          // Hire Date
              photo: row[15] ? String(row[15]).trim() : '',       // Photo
              cabinetKey: row[16] ? String(row[16]).trim() : '', // Cabinet Key
              gloveSize: row[17] ? String(row[17]).trim() : '',  // Glove Size

              // 离职相关
              reason: '',
              leavingData: '',

              // 假期信息 - 按照Excel表头顺序映射
              vacationBeginOne: this.formatExcelDate(row[18]),   // Vacation Start 1
              vacationEndOne: this.formatExcelDate(row[19]),     // Vacation End 1
              vacationBeginTwo: this.formatExcelDate(row[20]),   // Vacation Start 2
              vacationEndTwo: this.formatExcelDate(row[21]),     // Vacation End 2
              vacationBeginThree: this.formatExcelDate(row[22]), // Vacation Start 3
              vacationEndThree: this.formatExcelDate(row[23])    // Vacation End 3
            };

            importedEmployees.push(employee);
          }

          if (importedEmployees.length === 0) {
            this.$message.error('没有找到有效的员工数据');
            return;
          }

          // 验证数据
          let errorMessages = [];
          for (let i = 0; i < importedEmployees.length; i++) {
            const employee = importedEmployees[i];
            const rowNumber = i + 2; // Excel行号

            // 检查必填字段
            if (!employee.serialNumber) {
              errorMessages.push(`第${rowNumber}行：工号(Employee ID)不能为空`);
            }
            if (!employee.name) {
              errorMessages.push(`第${rowNumber}行：姓名(Name)不能为空`);
            }
            if (!employee.department) {
              errorMessages.push(`第${rowNumber}行：部门(Department)不能为空`);
            }

            // 验证日期格式
            if (employee.birthDate && !this.isValidDate(employee.birthDate)) {
              errorMessages.push(`第${rowNumber}行：生日(Birth Date)日期格式不正确 - ${employee.birthDate}`);
            }
            if (employee.hireDate && !this.isValidDate(employee.hireDate)) {
              errorMessages.push(`第${rowNumber}行：入职日期(Hire Date)格式不正确 - ${employee.hireDate}`);
            }

            // 验证假期日期
            const vacationErrors = this.validateVacationDatesForImport(employee, rowNumber);
            errorMessages = errorMessages.concat(vacationErrors);
          }

          if (errorMessages.length > 0) {
            this.$message.error({
              message: '导入失败，请检查以下问题：\n' + errorMessages.join('\n'),
              duration: 0,
              showClose: true
            });
            return;
          }

          // 批量添加员工
          this.batchAddEmployees(importedEmployees);

        } catch (error) {
          console.error('文件读取错误:', error);
          this.$message.error('文件读取失败，请检查文件格式是否正确');
        }
      };

      reader.onerror = () => {
        this.$message.error('文件读取失败');
      };

      reader.readAsArrayBuffer(fileToRead);
      this.$message.warning('已选择文件，正在处理...');
    },

// 批量添加员工（修改后的版本）
    async batchAddEmployees(employees) {
      try {
        let successCount = 0;
        let errorCount = 0;
        const errors = [];

        // 逐个添加员工
        for (let i = 0; i < employees.length; i++) {
          const employee = employees[i];

          try {
            const result = await this.$request.post('/addClerkNameClerkName', employee);

            if (result.code === 200) {
              successCount++;
            } else {
              errorCount++;
              errors.push(`第${i + 2}行：${result.message || '添加失败'}`);
            }
          } catch (error) {
            errorCount++;
            errors.push(`第${i + 2}行：网络错误 - ${error.message}`);
            console.error('添加员工错误:', error);
          }
        }

        // 显示导入结果
        if (errorCount === 0) {
          this.$message.success(`成功导入 ${successCount} 名员工`);
          this.refreshTableData(); // 刷新表格数据
        } else {
          let message = `导入完成：成功 ${successCount} 条，失败 ${errorCount} 条`;
          if (errors.length > 0) {
            message += '\n失败详情：\n' + errors.slice(0, 5).join('\n');
            if (errors.length > 5) {
              message += `\n... 还有 ${errors.length - 5} 条错误`;
            }
          }

          this.$message.warning({
            message: message,
            duration: 0,
            showClose: true
          });

          // 如果有部分成功，也刷新表格
          if (successCount > 0) {
            this.refreshTableData();
          }
        }

      } catch (error) {
        console.error('批量添加错误:', error);
        this.$message.error('批量导入过程中发生错误');
      }
    },

// 格式化Excel日期
    formatExcelDate(excelDate) {
      if (!excelDate) return '';

      // 如果是数字（Excel日期序列号）
      if (typeof excelDate === 'number') {
        return this.excelDateToYYYYMMDD(excelDate);
      }

      // 如果是字符串，尝试解析
      if (typeof excelDate === 'string') {
        // 移除可能的空格
        const cleanDate = excelDate.trim();

        // 检查是否是有效的日期字符串
        if (this.isValidDate(cleanDate)) {
          return cleanDate;
        }

        // 尝试解析其他格式的日期
        const parsedDate = new Date(cleanDate);
        if (!isNaN(parsedDate.getTime())) {
          return parsedDate.toISOString().split('T')[0];
        }
      }

      return '';
    },

// Excel日期转换（从您之前的代码中复用）
    excelDateToYYYYMMDD(serial) {
      if (!serial) return '';

      try {
        const utc_days = Math.floor(serial - 25569);
        const utc_value = utc_days * 86400;
        const date_info = new Date(utc_value * 1000);

        const fractional_day = serial - Math.floor(serial) + 0.0000001;
        let total_seconds = Math.floor(86400 * fractional_day);
        const seconds = total_seconds % 60;
        total_seconds -= seconds;
        const hours = Math.floor(total_seconds / (60 * 60));
        const minutes = Math.floor(total_seconds / 60) % 60;

        const date = new Date(date_info.getFullYear(), date_info.getMonth(), date_info.getDate(), hours, minutes, seconds);

        return date.toISOString().split('T')[0];
      } catch (error) {
        console.error('日期转换错误:', error);
        return '';
      }
    },

// 验证日期格式
    isValidDate(dateString) {
      if (!dateString) return false;

      const regex = /^\d{4}-\d{2}-\d{2}$/;
      if (!regex.test(dateString)) return false;

      const date = new Date(dateString);
      return date instanceof Date && !isNaN(date.getTime());
    },

// 验证导入数据的假期日期
    validateVacationDatesForImport(employee, rowNumber) {
      const errors = [];
      const vacationPeriods = [
        { start: employee.vacationBeginOne, end: employee.vacationEndOne, name: '第一段假期' },
        { start: employee.vacationBeginTwo, end: employee.vacationEndTwo, name: '第二段假期' },
        { start: employee.vacationBeginThree, end: employee.vacationEndThree, name: '第三段假期' }
      ];

      // 验证每个时间段
      for (let i = 0; i < vacationPeriods.length; i++) {
        const period = vacationPeriods[i];

        // 如果只有开始日期或只有结束日期
        if ((period.start && !period.end) || (!period.start && period.end)) {
          errors.push(`第${rowNumber}行：${period.name}的开始日期和结束日期必须同时填写或同时为空`);
        }

        // 如果开始日期晚于结束日期
        if (period.start && period.end && period.start > period.end) {
          errors.push(`第${rowNumber}行：${period.name}的开始日期不能晚于结束日期`);
        }
      }

      // 验证时间段交叉（只验证有值的时段）
      const validPeriods = vacationPeriods
          .filter(period => period.start && period.end)
          .map((period, index) => ({ ...period, originalIndex: index }));

      for (let i = 0; i < validPeriods.length; i++) {
        for (let j = i + 1; j < validPeriods.length; j++) {
          const periodA = validPeriods[i];
          const periodB = validPeriods[j];

          if (this.doPeriodsOverlap(periodA, periodB)) {
            errors.push(`第${rowNumber}行：${periodA.name}和${periodB.name}时间有交叉`);
          }
        }
      }

      return errors;
    },

// 检查时间段是否重叠
    doPeriodsOverlap(periodA, periodB) {
      const startA = new Date(periodA.start);
      const endA = new Date(periodA.end);
      const startB = new Date(periodB.start);
      const endB = new Date(periodB.end);

      return (startA <= endB && endA >= startB);
    },

// 批量添加员工
    clearAllFilters() {
      this.filterConditions = {
        shift: null,
        name: null,
        section: null,
        position: null
      };
      this.$message.success('已清除所有筛选条件');
    },

    generateFilters(prop) {
      const uniqueValues = [...new Set(this.clerkNameData.map(item => item[prop]))];
      return uniqueValues.filter(value => value != null && value !== '').map(value => ({
        text: value,
        value: value
      }))},
    filterHandler(value, row, column) {
      const property = column.property;
      return row[property] === value;
    },
    handleManualFilter() {
      console.log('手动筛选条件:', this.filterConditions);
    },
    calculateDays(periodIndex) {
      const periods = [
        { start: this.clerkNameForm.vacationBeginOne, end: this.clerkNameForm.vacationEndOne },
        { start: this.clerkNameForm.vacationBeginTwo, end: this.clerkNameForm.vacationEndTwo },
        { start: this.clerkNameForm.vacationBeginThree, end: this.clerkNameForm.vacationEndThree }
      ];

      const period = periods[periodIndex];

      if (period.start && period.end) {
        const startDate = new Date(period.start);
        const endDate = new Date(period.end);

        // 检查日期是否有效
        if (startDate > endDate) {
          return 0;
        }

        // 计算天数（包含开始和结束日期）
        const timeDiff = endDate.getTime() - startDate.getTime();
        const dayDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1; // +1 因为包含开始日期

        return dayDiff > 0 ? dayDiff : 0;
      }

      return 0;
    },

    // 获取假期时间段描述
    getVacationPeriodsDescription() {
      const periods = [];
      const periodNames = ['第一段', '第二段', '第三段'];

      for (let i = 0; i < 3; i++) {
        const days = this.calculateDays(i);
        if (days > 0) {
          periods.push(`${periodNames[i]} ${days}天`);
        }
      }

      return periods.length > 0 ? `包含: ${periods.join('，')}` : '';
    },

    // 修改现有的日期变化处理方法，添加天数计算
    handleBeginOneChange() {
      // 如果开始日期晚于结束日期，清空结束日期
      if (this.clerkNameForm.vacationBeginOne && this.clerkNameForm.vacationEndOne) {
        if (this.clerkNameForm.vacationBeginOne > this.clerkNameForm.vacationEndOne) {
          this.clerkNameForm.vacationEndOne = '';
        }
      }
      this.validatePeriodRealTime(0);
    },

    handleBeginTwoChange() {
      if (this.clerkNameForm.vacationBeginTwo && this.clerkNameForm.vacationEndTwo) {
        if (this.clerkNameForm.vacationBeginTwo > this.clerkNameForm.vacationEndTwo) {
          this.clerkNameForm.vacationEndTwo = '';
        }
      }
      this.validatePeriodRealTime(1);
    },

    handleBeginThreeChange() {
      if (this.clerkNameForm.vacationBeginThree && this.clerkNameForm.vacationEndThree) {
        if (this.clerkNameForm.vacationBeginThree > this.clerkNameForm.vacationEndThree) {
          this.clerkNameForm.vacationEndThree = '';
        }
      }
      this.validatePeriodRealTime(2);
    },
    // 退出登录
    logOut() {
      localStorage.removeItem('u_token');
      localStorage.removeItem('userName')
      this.$router.push('UserLogin')
    },

    // 查询用户信息的函数
    inquiry() {
      const useId = localStorage.getItem('userName').replace(/"/g, '');
      this.$request.post('/useQueryPower', {
        queryFiledName: 'goodProductCondition',
        userId: useId,
      }).then(result => {
        if (result.code === 401) {
          this.$router.push('UserLogin')
          alert("您未登录，请登录")
        } else {
          this.useName = result.data.name
          this.usePower = result.data.goodProductCondition
          this.useId = useId
        }
      })
    },

    // 语言选择
    languageSelect(language) {
      console.log(language)
    },

    // 按钮选择方法


    // 员工管理方法
    async queryClerkNameAll() {
      return this.$request.post('/queryClerkNameClerkName').then(result => {
        if (result.code === 401) {
          this.$router.push('UserLogin')
          alert("您未登录，请登录")
        }
        else {
          // 过滤掉已离职的员工
          return result.data.filter(item => item.reason !== null && item.reason==='')
        }
      })
    },

    // 查询离职员工数据
    async  queryResignedClerkData() {
      return this.$request.post('/queryClerkNameClerkName').then(result => {
        if (result.code === 401) {
          this.$router.push('UserLogin')
          alert("您未登录，请登录")
        }
        else {
          this.resignedClerkData = result.data.filter(item => item.reason != null && item.reason!=='')
        }
      })
    },

    // 生成UUID
    generateUUIDv4() {
      const bytes = new Uint8Array(16);
      crypto.getRandomValues(bytes);
      bytes[6] = (bytes[6] & 0x0f) | 0x40;
      bytes[8] = (bytes[8] & 0x3f) | 0x80;
      return Array.from(bytes, byte => {
        return byte.toString(16).padStart(2, '0');
      }).join('');
    },

    openDialog(doe, scope) {
      this.clerkNameDoe = doe
      this.clerkNameScope = scope
      if (doe === 1) {
        this.clerkNameForm = {
          id: '',
          create_time: '',
          update_time: '',
          creator: this.useName,
          process_status: '',
          sys_update_user: this.useName,
          sys_audit_user: '',
          sys_audit_time: '',
          sys_deleted: 0,
          serialNumber: '',
          name: '',
          department: '',
          section: '',
          position: '',
          shift: '',
          employee_number: '',
          gender: '',
          homeAddress: '',
          phone: '',
          birthDate: '',
          maritalStatus: '',
          children: '',
          commute: '',
          hireDate: '',
          photo: '',
          cabinetKey:'',
          gloveSize: ''
        };
        this.operatorListScope=null
            //上传人员的图像
        this.operatorListImageUrl=null
        this.dialogVisible = true;
      }
      else if (doe === 2) {
        this.clerkNameForm = _.cloneDeep(this.clerkNameScope.row)
        this.dialogVisible = true;
        console.log(this.clerkNameScope)
      }
      else if (doe === 3) {
        this.clerkNameForm = _.cloneDeep(this.clerkNameScope.row)
        this.resignDialogVisible = true;
        console.log(this.clerkNameScope)
      }
      else if (doe === 4) {
        this.clerkNameForm = _.cloneDeep(this.clerkNameScope.row)
        this.vacationVisible = true;
        console.log(this.clerkNameScope)
      }
    },

    // 验证假期时间
    validateVacationDates() {
      const periods = [
        { start: this.clerkNameForm.vacationBeginOne, end: this.clerkNameForm.vacationEndOne },
        { start: this.clerkNameForm.vacationBeginTwo, end: this.clerkNameForm.vacationEndTwo },
        { start: this.clerkNameForm.vacationBeginThree, end: this.clerkNameForm.vacationEndThree }
      ];

      // 过滤掉空的时间段
      const validPeriods = periods.filter(period => period.start && period.end);

      // 验证每个时间段本身的合理性（开始时间不能晚于结束时间）
      for (let i = 0; i < validPeriods.length; i++) {
        const period = validPeriods[i];
        if (period.start > period.end) {
          this.$message.error(`第${i + 1}段假期：开始时间不能晚于结束时间`);
          return false;
        }
      }

      // 验证时间段之间是否有交叉
      for (let i = 0; i < validPeriods.length; i++) {
        for (let j = i + 1; j < validPeriods.length; j++) {
          const periodA = validPeriods[i];
          const periodB = validPeriods[j];

          if (
              (periodA.start >= periodB.start && periodA.start <= periodB.end) ||
              (periodA.end >= periodB.start && periodA.end <= periodB.end) ||
              (periodB.start >= periodA.start && periodB.start <= periodA.end) ||
              (periodB.end >= periodA.start && periodB.end <= periodA.end)
          ) {
            this.$message.error(`第${i + 1}段假期和第${j + 1}段假期时间有交叉`);
            return false;
          }
        }
      }

      // 验证时间段是否重叠（完全包含）
      for (let i = 0; i < validPeriods.length; i++) {
        for (let j = i + 1; j < validPeriods.length; j++) {
          const periodA = validPeriods[i];
          const periodB = validPeriods[j];

          if (
              (periodA.start <= periodB.start && periodA.end >= periodB.end) ||
              (periodB.start <= periodA.start && periodB.end >= periodA.end)
          ) {
            this.$message.error(`第${i + 1}段假期和第${j + 1}段假期时间有重叠`);
            return false;
          }
        }
      }

      return true;
    },

    // 验证单个时间段
    validateSinglePeriod(startDate, endDate, periodName) {
      if (startDate && endDate) {
        if (startDate > endDate) {
          this.$message.error(`${periodName}：开始时间不能晚于结束时间`);
          return false;
        }
      }
      return true;
    },

    // 实时验证单个时间段（用于输入时即时验证）
    validatePeriodRealTime(periodIndex) {
      const periods = [
        { start: 'vacationBeginOne', end: 'vacationEndOne', name: '第一段假期' },
        { start: 'vacationBeginTwo', end: 'vacationEndTwo', name: '第二段假期' },
        { start: 'vacationBeginThree', end: 'vacationEndThree', name: '第三段假期' }
      ];

      const period = periods[periodIndex];
      if (this.clerkNameForm[period.start] && this.clerkNameForm[period.end]) {
        this.validateSinglePeriod(
            this.clerkNameForm[period.start],
            this.clerkNameForm[period.end],
            period.name
        );
      }
    },

    // 检查日期是否有错误
    hasDateError(periodIndex) {
      const periods = [
        { start: this.clerkNameForm.vacationBeginOne, end: this.clerkNameForm.vacationEndOne },
        { start: this.clerkNameForm.vacationBeginTwo, end: this.clerkNameForm.vacationEndTwo },
        { start: this.clerkNameForm.vacationBeginThree, end: this.clerkNameForm.vacationEndThree }
      ];

      const period = periods[periodIndex];
      if (period.start && period.end) {
        return period.start > period.end;
      }
      return false;
    },

    // 重置日期错误状态
    resetDateErrors() {
      this.dateErrors = [false, false, false];
    },

    async editorClerkNameOk() {
      try {
        // 如果是 vacation 编辑，先验证时间
        if (this.clerkNameDoe === 4) {
          if (!this.validateVacationDates()) {
            return; // 验证失败，不执行保存
          }
        }

        let result;
        let updateData = this.prepareUpdateData(); // 准备完整的数据

        if (this.clerkNameDoe === 1) { // 添加
          this.clerkNameForm.id = this.generateUUIDv4();

          if (this.operatorListFile) { // 有照片上传
            // 准备照片数据
            const fileName = this.generateUniqueId() + '.' +
                this.operatorListFile.name.split('.').pop();

            // 更新表单中的照片字段
            this.clerkNameForm.photo = fileName;

            // 准备文件上传表单
            const formData = new FormData();
            formData.append('file', this.operatorListFile.raw);
            formData.append('fileName', fileName);
            formData.append('type', 0); // 新增
            formData.append('oldFileName', '');

            // 添加员工数据到formData
            const employeeData = JSON.stringify(this.clerkNameForm);
            formData.append('employeeData', employeeData);

            // 先上传文件
            await this.$requestFile.post('addClerkNameClerkNameFile', formData);

            // 然后添加员工信息（现在photo字段已经在form中）
            result = await this.$request.post('/addClerkNameClerkName', this.clerkNameForm);
          } else { // 没有照片上传
            result = await this.$request.post('/addClerkNameClerkName', this.clerkNameForm);
          }
        } else { // 编辑操作
          if (this.operatorListFile) { // 有照片上传
            // 准备照片数据
            const fileName = this.generateUniqueId() + '.' +
                this.operatorListFile.name.split('.').pop();

            // 更新表单中的照片字段
            updateData.photo = fileName;

            // 准备文件上传表单
            const formData = new FormData();
            formData.append('file', this.operatorListFile.raw);
            formData.append('fileName', fileName);
            formData.append('type', 1); // 更新

            // 获取当前员工的旧照片名（如果有）
            const currentEmployee = this.clerkNameScope?.row;
            if (currentEmployee && currentEmployee.photo) {
              formData.append('oldFileName', currentEmployee.photo);
            } else {
              formData.append('oldFileName', '');
            }

            // 添加员工数据到formData
            const employeeData = JSON.stringify(updateData);
            formData.append('employeeData', employeeData);

            // 先上传新照片
            await this.$requestFile.post('addClerkNameClerkNameFile', formData);

            // 然后更新员工信息（photo字段已经在updateData中）
            result = await this.$request.post('/editClerkNameClerkName', updateData);
          } else { // 没有照片上传，只更新其他字段
            result = await this.$request.post('/editClerkNameClerkName', updateData);
          }
        }

        if (result.code === 401) {
          this.$router.push('UserLogin');
          this.$message.error("您未登录，请登录");
        } else {
          this.$message.success(
              this.clerkNameDoe === 1 ? "successful add" :
                  this.clerkNameDoe === 2 ? "successful edit" :
                      this.clerkNameDoe === 3 ? "successful leaving reason" :
                          "successful vacation update"
          );

          // 强制关闭所有弹窗
          this.forceCloseAllDialogs();

          // 刷新表格数据
          await this.refreshTableData();
        }
      } catch (error) {
        this.$message.error(
            this.clerkNameDoe === 1 ? "添加失败" :
                this.clerkNameDoe === 2 ? "修改失败" :
                    this.clerkNameDoe === 3 ? "离职原因更新失败" :
                        "假期信息更新失败"
        );
        console.error(error);
      }
    },

    // 强制关闭所有弹窗
    forceCloseAllDialogs() {
      this.dialogVisible = false;
      this.resignDialogVisible = false;
      this.vacationVisible = false;

      // 使用 $nextTick 确保 DOM 更新
      this.$nextTick(() => {
        this.dialogVisible = false;
        this.resignDialogVisible = false;
        this.vacationVisible = false;
      });
    },

    // 准备更新数据，只包含必要的字段
// 准备更新数据，只包含必要的字段
    // 方法2：更保守的更新方法
    prepareUpdateData() {
      const baseFields = {
        id: this.clerkNameForm.id,
        update_time: new Date().toISOString(),
        sys_update_user: this.useName
      };

      let updateData;

      if (this.clerkNameDoe === 4) {
        // 创建包含所有必要字段的对象
        updateData = {
          // 基本信息
          id: this.clerkNameForm.id,
          serialNumber: this.clerkNameForm.serialNumber || this.clerkNameScope.row.serialNumber,
          name: this.clerkNameForm.name || this.clerkNameScope.row.name,
          department: this.clerkNameForm.department || this.clerkNameScope.row.department,
          section: this.clerkNameForm.section || this.clerkNameScope.row.section,
          position: this.clerkNameForm.position || this.clerkNameScope.row.position,
          shift: this.clerkNameForm.shift || this.clerkNameScope.row.shift,
          employeeNumber: this.clerkNameForm.employeeNumber || this.clerkNameScope.row.employeeNumber,
          gender: this.clerkNameForm.gender || this.clerkNameScope.row.gender,
          homeAddress: this.clerkNameForm.homeAddress || this.clerkNameScope.row.homeAddress,
          phone: this.clerkNameForm.phone || this.clerkNameScope.row.phone,
          birthDate: this.clerkNameForm.birthDate || this.clerkNameScope.row.birthDate,
          maritalStatus: this.clerkNameForm.maritalStatus || this.clerkNameScope.row.maritalStatus,
          children: this.clerkNameForm.children || this.clerkNameScope.row.children,
          commute: this.clerkNameForm.commute || this.clerkNameScope.row.commute,
          hireDate: this.clerkNameForm.hireDate || this.clerkNameScope.row.hireDate,
          photo: this.clerkNameForm.photo || this.clerkNameScope.row.photo,
          cabinetKey: this.clerkNameForm.cabinetKey || this.clerkNameScope.row.cabinetKey,
          gloveSize: this.clerkNameForm.gloveSize || this.clerkNameScope.row.gloveSize,
          reason: this.clerkNameForm.reason || this.clerkNameScope.row.reason,
          leavingData: this.clerkNameForm.leavingData || this.clerkNameScope.row.leavingData,

          // 休假信息
          vacationBeginOne: this.clerkNameForm.vacationBeginOne || '',
          vacationEndOne: this.clerkNameForm.vacationEndOne || '',
          vacationBeginTwo: this.clerkNameForm.vacationBeginTwo || '',
          vacationEndTwo: this.clerkNameForm.vacationEndTwo || '',
          vacationBeginThree: this.clerkNameForm.vacationBeginThree || '',
          vacationEndThree: this.clerkNameForm.vacationEndThree || '',

          // 系统字段
          ...baseFields
        };
      } else {
        updateData = {
          ...this.clerkNameForm,
          ...baseFields
        };
      }

      console.log('更新数据检查 - 职位:', updateData.position);
      console.log('更新数据检查 - 科室:', updateData.section);

      return updateData;
    },

    // 关闭所有弹窗
    closeDialogs() {
      this.dialogVisible = false;
      this.resignDialogVisible = false;
      this.vacationVisible = false;
    },

    refreshTableData() {
      this.queryClerkNameAll().then(data => {
        this.clerkNameData = data;
      });
    },
  },
  watch: {
    clerkNameData: {
      handler() {
        if (this.buttonDoe === 6 && this.orgChartInstance) {
          this.$nextTick(() => {
            this.generateOrgChart();
          });
        }
      },
      deep: true
    },


    // 监听部门变化，更新科室选项
    'clerkNameForm.department'(newVal) {
      if (newVal) {
        const selectedDept = this.departmentOptions.find(dept => dept.value === newVal);
        this.sectionOptions = selectedDept ? selectedDept.sections : [];
        this.clerkNameForm.section = ''; // 重置科室
        this.clerkNameForm.position = ''; // 重置职位
        this.positionOptions = []; // 清空职位选项
      } else {
        this.sectionOptions = [];
        this.clerkNameForm.section = '';
        this.clerkNameForm.position = '';
        this.positionOptions = [];
      }
    },
    // 监听科室变化，更新职位选项
    'clerkNameForm.section'(newVal) {
      if (newVal && this.clerkNameForm.department) {
        const selectedDept = this.departmentOptions.find(dept => dept.value === this.clerkNameForm.department);
        const selectedSection = selectedDept.sections.find(sec => sec.value === newVal);
        this.positionOptions = selectedSection ? selectedSection.positions : [];
        this.clerkNameForm.position = ''; // 重置职位
      } else {
        this.positionOptions = [];
        this.clerkNameForm.position = '';
      }
    }
  },

  mounted() {
    this.inquiry();
    this.queryClerkNameAll().then(data => {
      this.clerkNameData = data;
    });
    this.fetchCabinets();
  },

  beforeDestroy() {
    // 清理 ECharts 实例
    if (this.orgChartInstance) {
      this.orgChartInstance.dispose();
    }
  }
}
</script>

<style scoped>
/* 原有样式保持不变 */
/* 统计弹窗样式 */
.statistics-container {
  max-height: 600px;
  overflow-y: auto;
}

.total-count {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 15px;
  border-radius: 8px;
  text-align: center;
  margin-bottom: 20px;
  font-size: 18px;
}

.department-section {
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  margin-bottom: 15px;
  overflow: hidden;
}

.department-header {
  background: #409EFF;
  color: white;
  padding: 12px 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.department-header h3 {
  margin: 0;
  font-size: 16px;
}

.count-badge {
  background: rgba(255, 255, 255, 0.2);
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
}

.section-item {
  border-bottom: 1px solid #f0f0f0;
}

.section-item:last-child {
  border-bottom: none;
}

.section-header {
  background: #f5f7fa;
  padding: 10px 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e6e6e6;
}

.positions-list {
  padding: 10px;
}

.position-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px dashed #f0f0f0;
}

.position-item:last-child {
  border-bottom: none;
}

.position-name {
  color: #606266;
}

.position-count {
  background: #67C23A;
  color: white;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
  min-width: 40px;
  text-align: center;
}

/* 统计弹窗自定义样式 */
.statistics-modal .el-message-box__message {
  padding: 0 !important;
}
.el-footer {
  background-color: #ffffff;
  color: #333;
  text-align: center;
  border-width: 3px;
  border-color: blue;
  border-style: solid;
  padding: 10px;
  border-left-color: white;
  border-top: white;
}

.el-aside {
  background-color: #ffffff;
  color: #333;
  text-align: center;
  border-width: 3px;
  border-color: blue;
  border-style: solid;
  padding: 10px;
  height: 89vh;
}

.el-main {
  color: #333;
  text-align: center;
  border-width: 3px;
  border-color: blue;
  border-left-color: white;
  border-style: solid;
  padding: 10px;
  overflow: auto;
}

body > .el-container {
  margin-bottom: 40px;
}

.headMain {
  color: #ffffff;
  font-size: 18px;
}

.center-text {
  margin-left: auto;
  margin-right: auto;
}

.el-table {
  margin-top: 20px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

.el-table th {
  background-color: #f5f7fa !important;
}
.aside-button {
  width: 100%;
  margin: 0 0 10px 0;
  text-align: left;
  padding: 12px 16px;
  border-radius: 0;
}

.el-aside {
  padding: 0 !important;
  background-color: #ffffff;
  border-right: 3px solid blue;
}
.el-aside {
  padding: 0 !important;
  background-color: #ffffff;
  border-right: 3px solid blue;
}
.cabinet-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 10px;
  width: 100%;
  margin-top: 20px;
}

.cabinet-item {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 8px;
  text-align: center;
  cursor: pointer;
  min-height: 60px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background-color: #f5f7fa;
  transition: all 0.3s;
}

.cabinet-item:hover {
  background-color: #ecf5ff;
  border-color: #c6e2ff;
}

.cabinet-number {
  font-weight: bold;
  margin-bottom: 4px;
}
.cabinet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  width: 100%;
  margin-top: 20px;
  padding: 10px;
}

.cabinet-item {
  border: 2px solid #dcdfe6;
  border-radius: 8px;
  padding: 12px;
  text-align: center;
  cursor: pointer;
  min-height: 100px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background-color: #f5f7fa;
  transition: all 0.3s ease;
  position: relative;
}

.cabinet-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.cabinet-number {
  font-weight: bold;
  font-size: 16px;
  color: #409EFF;
  margin-bottom: 8px;
}

.cabinet-info {
  margin-bottom: 8px;
}

.location {
  font-size: 12px;
  color: #909399;
  margin-bottom: 4px;
}

.cabinet-gender {
  font-size: 12px;
  color: #67C23A;
  font-weight: 500;
}
/* 照片上传样式 */
.photo-upload-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.photo-uploader {
  width: 100%;
}

.photo-placeholder,
.photo-preview {
  width: 120px;
  height: 120px;
  border-radius: 6px;
  overflow: hidden;
  position: relative;
  margin: 0 auto;
  border: 1px dashed #dcdfe6;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s;
}

.photo-placeholder:hover,
.photo-preview:hover {
  border-color: #409EFF;
}

.photo-icon {
  font-size: 28px;
  color: #8c939d;
}

.photo-text {
  margin-top: 8px;
  font-size: 12px;
  color: #8c939d;
}

.photo-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
  color: white;
}

.photo-preview:hover .photo-overlay {
  opacity: 1;
}

.photo-overlay i {
  font-size: 20px;
  margin-bottom: 5px;
}

.photo-tips {
  margin-top: 8px;
  font-size: 12px;
  color: #909399;
  text-align: center;
}
.employee-info {
  font-size: 14px;
  color: #E6A23C;
  font-weight: bold;
  background: rgba(230, 162, 60, 0.1);
  padding: 4px 8px;
  border-radius: 4px;
  margin-top: 4px;
}

.empty-cabinet {
  font-size: 12px;
  color: #909399;
  font-style: italic;
  margin-top: 4px;
}

.occupied {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
}

.occupied .cabinet-number {
  color: #67C23A;
}
.department-info {
  font-size: 12px;
  color: #606266;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.occupied {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
}
   /* 其他现有样式... */

   /* 天数显示样式 */
 .vacation-days {
   color: #409EFF;
   font-weight: bold;
   margin-left: 10px;
 }

.vacation-days.invalid {
  color: #F56C6C;
}

/* 总天数统计样式 */
.total-days {
  background-color: #f0f9ff;
  border: 1px solid #409EFF;
  border-radius: 4px;
  padding: 8px 12px;
  margin: 10px 0;
}

.total-days h4 {
  margin: 0 0 5px 0;
  color: #409EFF;
}

.total-days p {
  margin: 0;
  color: #606266;
}
.table-container {
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

/* 为每日数据表格添加斑马纹 */
.daily-table .el-table__row:nth-child(2n) {
  background-color: #fafafa;
}

.daily-table .el-table__row:hover {
  background-color: #f5f7fa;
}
.cabinet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  width: 100%;
  margin-top: 20px;
  padding: 10px;
}

.cabinet-item {
  border: 2px solid #dcdfe6;
  border-radius: 8px;
  padding: 12px;
  text-align: center;
  cursor: pointer;
  min-height: 100px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background-color: #f5f7fa;
  transition: all 0.3s ease;
  position: relative;
}

.cabinet-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.cabinet-number {
  font-weight: bold;
  font-size: 16px;
  color: #409EFF;
  margin-bottom: 8px;
}

.cabinet-info {
  margin-bottom: 8px;
}

.location {
  font-size: 12px;
  color: #909399;
  margin-bottom: 4px;
}

.cabinet-gender {
  font-size: 12px;
  color: #67C23A;
  font-weight: 500;
}

.employee-info {
  font-size: 14px;
  color: #E6A23C;
  font-weight: bold;
  background: rgba(230, 162, 60, 0.1);
  padding: 4px 8px;
  border-radius: 4px;
  margin-top: 4px;
}

.empty-cabinet {
  font-size: 12px;
  color: #909399;
  font-style: italic;
  margin-top: 4px;
}

.occupied {
  background-color: #f0f9eb;
  border-color: #e1f3d8;
}

.occupied .cabinet-number {
  color: #67C23A;
}
</style>